﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Security.Permissions;
using System.Web.Mvc;

namespace Mvc.ActionFilters
{
	/// <summary>
	/// http://weblogs.asp.net/rashid/archive/2009/04/29/fun-with-http-headers-in-asp-net-mvc-action-filters.aspx
	/// Auto redirect to a specific url after a certain interval
	/// <remarks>
	/// If the browsers is idle for the specified period, it will automatically redirect 
	/// to that Action. if you do not specify any action/controller/route (Index4) it will 
	/// auto refresh the current url.
	/// </remarks>
	/// <example>
	/// [AutoRefresh(ControllerName = "Home", ActionName = "About", DurationInSeconds = 10)]
	/// public ActionResult Index1()
	/// 
	/// [AutoRefresh(ActionName = "About", DurationInSeconds = 15)]
	/// public ActionResult Index2()
	/// 
	/// [AutoRefresh(RouteName = "ByFavoriteRoute", DurationInSeconds = 30)]
	/// public ActionResult Index3()
	/// 
	/// [AutoRefresh(DurationInSeconds = 45)]
	/// public ActionResult Index4()
	/// </example>
	/// </summary>
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
	[AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal)]
	public class AutoRefreshAttribute : ActionFilterAttribute
	{
		public const int DefaultDurationInSeconds = 300; // 5 Minutes

		public AutoRefreshAttribute()
		{
			DurationInSeconds = DefaultDurationInSeconds;
		}

		public int DurationInSeconds
		{
			get;
			set;
		}

		public string RouteName
		{
			get;
			set;
		}

		public string ControllerName
		{
			get;
			set;
		}

		public string ActionName
		{
			get;
			set;
		}

		public override void OnResultExecuted(ResultExecutedContext filterContext)
		{
			string url = BuildUrl(filterContext);
			string headerValue = string.Concat(DurationInSeconds, ";Url=", url);

			filterContext.HttpContext.Response.AppendHeader("Refresh", headerValue);

			base.OnResultExecuted(filterContext);
		}

		private string BuildUrl(ControllerContext filterContext)
		{
			UrlHelper urlHelper = new UrlHelper(filterContext.RequestContext);
			string url;

			if (!string.IsNullOrEmpty(RouteName))
			{
				url = urlHelper.RouteUrl(RouteName);
			}
			else if (!string.IsNullOrEmpty(ControllerName) && !string.IsNullOrEmpty(ActionName))
			{
				url = urlHelper.Action(ActionName, ControllerName);
			}
			else if (!string.IsNullOrEmpty(ActionName))
			{
				url = urlHelper.Action(ActionName);
			}
			else
			{
				url = filterContext.HttpContext.Request.RawUrl;
			}

			return url;
		}
	}
}
